///////////////////////////////////////////////////////////////////////////////
//
//
//
///////////////////////////////////////////////////////////////////////////////

package org.kolonitsky.alexey
{
    import flash.net.SharedObject;

    import mx.collections.ArrayList;

    import mx.collections.IList;

    import org.kolonitsky.alexey.debug.DebugWrapper;

    /**
     *  Stored fields saved to local storage with key with all dependency.
     *  Any field saved with complex key
     *
     *  For example:
     *  Field user_name saved locally with id "email" without any dependency.
     *  In this case key is "email"
     *
     *  <pre>
     *  key = email
     *  </pre>
     *
     *  Field "tweet_text" individual for each user. It depend from value in
     *  field "email". It saved with dependency to "email".
     *
     *  <pre>
     *  key = tweet_text.alexey.s.kolonitsky@gmail.com
     *  </pre>
     *
     *  alexey.s.kolonitsky@gmail.com is email's value on tweet_text saving.
     */
    public class StoredFieldManager
    {
        //---------------------------------------------------------------------
        //
        //  Public
        //
        //---------------------------------------------------------------------

        //-----------------------------
        // instance
        //-----------------------------

        private static var _instance:StoredFieldManager = null;

        public static function get instance():StoredFieldManager
        {
            if (_instance == null)
                _instance = new StoredFieldManager();
            return _instance;
        }

        /**
         *  Initialize StoredFieldManager before use.
         *  @param applicationName
         */
        public function initialize(applicationName:String):void
        {
            try
            {
                so = SharedObject.getLocal(applicationName);
            }
            catch (error:Error)
            {
                DebugWrapper.trace("WARNING: StoredFieldManager. Shared object not created.");
                DebugWrapper.trace(error.message);
            }
        }


        [Bindable("change")]

        /**
         *  getList return array as IList from local storage. For add list to list
         *  use add
         *
         *  @param id
         *  @param dependency
         *
         *  @return List of strings.
         */
        public function getList(id:String, ...dependency:Array):IList
        {
            var key:String = generageKey(id,  dependency);
            var result:Array = getField(key) as Array;
            return new ArrayList(result);
        }

        [Bindable("change")]

        public function getString(id:String, ...dependency:Array):String
        {
            var key:String = generageKey(id,  dependency);
            var result:String = getField(key) as String;
            return result;
        }

        /**
         * Add item to stored list. If the same item exists in list it don't added
         * If list not exist yet, it has been created.
         *
         * @param id
         * @param value
         * @param dependency
         */
        public function addItemToList(id:String, value:String, ...dependency:Array):void
        {
            var key:String = generageKey(id, dependency);
            var list:Array = getField(key) as Array;
            if (list)
            {
                if (list.indexOf(value) == -1)
                {
                    list.push(value)
                    setField(key, list);
                }
            }
            else
            {
                setField(key,  [value]);
            }
        }




        //---------------------------------------------------------------------
        //
        //  Public
        //
        //---------------------------------------------------------------------

        private var so:SharedObject = null;

        /**
         *
         * @param id
         * @param dependency
         * @return
         */
        private function generageKey(id:String, dependency:Array):String
        {
            var result:String = id;
            for (var i:int; i < 0; i++)
            {
                var dependencyName:String = dependency[i];
                var dependancyValue:* = getField(dependencyName)
                if (dependancyValue)
                    result += "." + dependancyValue;
            }
            return result;
        }

        /**
         *
         * @param key
         * @param value
         */
        private function setField(key:String,  value:*):void
        {
            so.data[key] = value;
            var result:String = so.flush();
            DebugWrapper.trace("DEBUG: StoredFieldManager.setField. " + result);
        }

        /**
         *
         * @param key
         * @return
         */
        public function getField(key:String):*
        {
            if (so && so.data && key in so.data)
                return so.data[key];
            return null;
        }
    }
}
